package com.puzzud.engine.video;

import com.puzzud.engine.video.VideoObject;
import com.puzzud.engine.video.VideoImage;
import com.puzzud.engine.video.VideoSprite;

import com.puzzud.engine.video.VideoObject2D;
import com.puzzud.engine.utility.GameShell;

import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.color.ColorSpace;
import java.util.Vector;

// VideoDisplay
public class VideoDisplay extends VideoObject2D
{
	Image backBufferImage;
	Graphics backBufferGraphics;
	int frameRate;
	
	private Color backgroundColor;
	private float[] backgroundColorWeight;

        private Color printColor;
	private float[] printColorWeight;
	
	int realWidth;
	int realHeight;
	
	AffineTransform affineTransform;
	
	GameShell gameShell;
	
	public VideoDisplay( GameShell gs )
	{
		super();
		
		gameShell = gs;
		
		gameShell.setDoubleBuffered( true );
		
		affineTransform = new AffineTransform();
		
		setRealDimensions( gs.getSize().width, gs.getSize().height );
		setDimensions( getRealWidth(), getRealHeight() );
		
		frameRate = 60;
		backgroundColorWeight = new float[] { 0.0f, 0.0f, 0.0f };
		setBackgroundColor( backgroundColorWeight );

                printColorWeight = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
		setPrintColor( printColorWeight );
	}
	
	public VideoDisplay( int width, int height, GameShell gs )
	{
		super();
		
		gameShell = gs;
		
		gameShell.setDoubleBuffered( true );
		
		affineTransform = new AffineTransform();

		setRealDimensions( width, height );
                setDimensions( ( int )gameShell.getParent().getSize().getWidth(),
                                   ( int )gameShell.getParent().getSize().getHeight() );
		
		frameRate = 60;
		backgroundColorWeight = new float[] { 0.0f, 0.0f, 0.0f };
		setBackgroundColor( backgroundColorWeight );

                printColorWeight = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
		setPrintColor( printColorWeight );
	}
	
	protected void setRealDimensions( int width, int height )
	{
		backBufferImage = gameShell.createImage( width, height );
		backBufferGraphics = backBufferImage.getGraphics();
		
		realWidth = width;
		realHeight = height;
	}
	
	public void setDimensions( int width, int height )
	{
		super.setDimensions( width, height );

                gameShell.setSize( width, height );

                affineTransform = new AffineTransform();
		affineTransform.translate( 0, 0 );
		affineTransform.scale( getXScale(), getYScale() );
	}
	
	public int getRealWidth()
	{
		return( realWidth );
	}
	
	public int getRealHeight()
	{
		return( realHeight );
	}
	
	public void draw( VideoImage tempVideoImage )
	{
            tempVideoImage.drawOnTo( this );
	}

        public void draw( VideoSprite tempVideoSprite )
	{
            tempVideoSprite.drawOnTo( this );
	}
	
	public void clear()
	{
		backBufferGraphics.setColor( backgroundColor );
		backBufferGraphics.fillRect( 0, 0, getRealWidth(), getRealHeight() );
	}
	
	public void display()
	{
		// Display backbuffer on this display.
		
		if( isScaled() )
		{
			//Graphics2D g2d = getBuffer();
			Graphics2D g2d = ( Graphics2D )gameShell.graphicsContext;

                        if( getScaleType() == VideoObject2D.SCALE_TYPE_EXACT )
                        {
                            g2d.setRenderingHint( RenderingHints.KEY_INTERPOLATION,
                                                 RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR );

                        }
                        else
                        {
                             g2d.setRenderingHint( RenderingHints.KEY_INTERPOLATION,
                                                   RenderingHints.VALUE_INTERPOLATION_BILINEAR  );
                        }
                        
			//g2d.setTransform( affineTransform );    // NOTE: This state causes a flash sometimes when external object resizes it.
                        //gameShell.graphicsContext.drawImage( backBufferImage, 0, 0, gameShell );

                        gameShell.graphicsContext.drawImage( backBufferImage, 0, 0, this.width, this.height, gameShell );
		}
		else
		{
			gameShell.graphicsContext.drawImage( backBufferImage, 0, 0, null );
		}
	}
	
	public int getFrameRate()
	{
		return( frameRate );
	}
	
	public void setFrameRate( int frameRate )
	{
		this.frameRate = frameRate;
	}
	
	public float[] getBackgroundColor()
	{
		return( backgroundColorWeight );
	}
	
	public void setBackgroundColor( float[] color )
	{
		backgroundColorWeight[0] = color[0];
		backgroundColorWeight[1] = color[1];
		backgroundColorWeight[2] = color[2];
		
		//backgroundColor = null;
		backgroundColor = new Color( backgroundColorWeight[0], backgroundColorWeight[1], backgroundColorWeight[2] );
		//gameShell.setBackground( backgroundColor );	// This actually changes the widget's background color... wanted?
	}
	
	public Graphics2D getBuffer()
	{
		return( ( Graphics2D )backBufferGraphics );
	}

        public float[] getPrintColor()
	{
		return( printColorWeight );
	}

	public void setPrintColor( float[] color )
	{
		printColorWeight[0] = color[0];
		printColorWeight[1] = color[1];
		printColorWeight[2] = color[2];
                
                // Check if an alpha component was requested.
                if( color.length == 4 )
                {
                    printColorWeight[3] = color[3];
                    printColor = new Color( printColorWeight[0], printColorWeight[1], printColorWeight[2], printColorWeight[3] );
                }
                else
                {
                    printColor = new Color( printColorWeight[0], printColorWeight[1], printColorWeight[2] );
                }
	}
	
	public void print( String line, int x, int y )
	{
            backBufferGraphics.setColor( printColor );
            backBufferGraphics.drawString( line, x, y );
	}
}